package cn.neo.hhrpc.core.config;


import cn.neo.hhrpc.core.api.*;
import cn.neo.hhrpc.core.cluster.GrayRouter;
import cn.neo.hhrpc.core.cluster.RoundRibbonLoadBalancer;
import cn.neo.hhrpc.core.consumer.ConsumerBootstrap;
import cn.neo.hhrpc.core.filter.CacheFilter;
import cn.neo.hhrpc.core.filter.MockFilter;
import cn.neo.hhrpc.core.filter.ParameterFilter;
import cn.neo.hhrpc.core.registry.RegistryCenter;
import cn.neo.hhrpc.core.registry.hh.HHRegistryCenter;
import cn.neo.hhrpc.core.registry.zk.ZkRegistryCenter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.Order;

import java.util.List;

@Slf4j
@Configuration
@Import({AppConfigProperties.class, ConsumerConfigProperties.class})
public class ConsumerConfig {


    @Autowired
    AppConfigProperties appConfigProperties;

    @Autowired
    ConsumerConfigProperties consumerConfigProperties;


//    @Bean
//    @ConditionalOnMissingBean
//    @ConditionalOnProperty(prefix = "apollo.bootstrap", value = "enabled")
//    ApolloChangedListener consumer_apolloChangedListener() {
//        return new ApolloChangedListener();
//    }
    @Bean
    ConsumerBootstrap consumerBootstrap () {
        return new ConsumerBootstrap();
    }

    @Bean
    // 启动类中的ApplicationRunner优先级高于此处，会导致userService未被加载到容器中就使用，所以要优先启动此处的ApplicationRunner用于加载userService到容器中，防止空指针
    @Order(Integer.MIN_VALUE)
    public ApplicationRunner consumerBootstrap_runner(@Autowired ConsumerBootstrap consumerBootstrap) {
        return x -> {
            log.info("consumerBootstrap starting....");
            consumerBootstrap.start();
            log.info("consumerBootstrap ending....");
        };
    }


    @Bean(initMethod = "start", destroyMethod = "stop")
    // 当具有相同类型的bean注册时(provider也会注册)，它会保证当前实例只有一个
    @ConditionalOnMissingBean
    public RegistryCenter consumer_rc() {
        return new HHRegistryCenter();
    }




    @Bean
    public LoadBalancer loadBalancer() {
//        return LoadBalancer.Default;
//        return new RandomLoadBalancer();
        return new RoundRibbonLoadBalancer();
    }

    @Bean
    public Router router() {
        return new GrayRouter(consumerConfigProperties.getGrayRatio());
    }

    @Bean
    public Filter  filter(){
        return new ParameterFilter();
    }

    @Bean
    @RefreshScope // context.refresh
    public RpcContext createContext(@Autowired Router router,
                                    @Autowired LoadBalancer loadBalancer,
                                    @Autowired List<Filter> filters) {
        RpcContext context = new RpcContext();
        context.setRouter(router);
        context.setLoadBalancer(loadBalancer);
        context.setFilters(filters);
        context.getParameters().put("app.id", appConfigProperties.getId());
        context.getParameters().put("app.namespace", appConfigProperties.getNamespace());
        context.getParameters().put("app.env", appConfigProperties.getEnv());
        context.setConsumerProperties(consumerConfigProperties);
        return context;
    }

}
